r""" 正则表达式操作 (RE).

这个模块提供了与 Perl 语言类似的正则表达式匹配操作。  既支持 <统一码> 字符串 (str) ，也支持8位字节串 (字节); 
模式和要处理的字符串都可以包含空字节和超出 <ASCII码> 范围的字符。

正则表达式可以包含普通或者特殊字符。绝大部分普通字符，比如 'A', 'a', 或者 '0'，都是最简单的正则表达式。它们就匹配自身。
你可以拼接普通字符，所以 last 匹配字符串 'last'.
 
特殊字符是：
    "."      (点) 在默认模式，匹配除了换行的任意字符。如果指定了标签 <点全部> ，它将匹配包括换行符的任意字符。
    "^"      (插入符号) 匹配字符串的开头， 并且在 <多行> 模式也匹配换行后的首个符号。
    "$"      匹配字符串尾或者换行符的前一个字符，在 <多行> 模式匹配换行符的前一个字符。 foo 匹配 'foo' 和 'foobar' ,
             但正则 foo$ 只匹配 'foo'。更有趣的是， 在 'foo1\nfoo2\n' 搜索 foo.$ ，通常匹配'foo2' ，但在 <多行> 
             模式 ，可以匹配到 'foo1' ；在 'foo\n' 搜索 $ 会找到两个空串：一个在换行前，一个在字符串最后。
    "*"      对它前面的正则式匹配0到任意次重复， 尽量多的匹配字符串。 ab* 会匹配 'a'， 'ab'， 或者 'a'``后面跟随任意个 ``'b'。
    "+"      对它前面的正则式匹配1到任意次重复。 ab+ 会匹配 'a' 后面跟随1个以上到任意个 'b'，它不会匹配 'a'。
    "?"      对它前面的正则式匹配0到1次重复。 ab? 会匹配 'a' 或者 'ab'。
    *?,+?,?? '*', '+'，和 '?' 修饰符都是 贪婪的；它们在字符串进行尽可能多的匹配。有时候并不需要这种行为。如果正则式 <.*> 希望找到 
             '<a> b <c>'，它将会匹配整个字符串，而不仅是 '<a>'。在修饰符之后添加 ? 将使样式以 非贪婪`方式或者 :dfn:`最小 方式进行匹配； 
             尽量 少 的字符将会被匹配。 使用正则式 <.*?> 将会仅仅匹配 '<a>'。
    {m,n}    对正则式进行 m 到 n 次匹配，在 m 和 n 之间取尽量多。 比如，a{3,5} 将匹配 3 到 5个 'a'。忽略 m 意为指定下界为0，忽略 n 
             指定上界为无限次。 比如 a{4,}b 将匹配 'aaaab' 或者1000个 'a' 尾随一个 'b'，但不能匹配 'aaab'。逗号不能省略，否则无法辨别修饰符应该忽略哪个边界。
    {m,n}?   前一个修饰符的非贪婪模式，只匹配尽量少的字符次数。比如，对于 'aaaaaa'， a{3,5} 匹配 5个 'a' ，而 a{3,5}? 只匹配3个 'a'。
    "\\"     转义特殊字符（允许你匹配 '*', '?', 或者此类其他），或者表示一个特殊序列；特殊序列之后进行讨论。如果你没有使用原始字符串（ r'raw' ）来表达样式，
             要牢记Python也使用反斜杠作为转义序列；如果转义序列不被Python的分析器识别，反斜杠和字符才能出现在字符串中。如果Python可以识别这个序列，
             那么反斜杠就应该重复两次。这将导致理解障碍，所以高度推荐，就算是最简单的表达式，也要使用原始字符串。
    []       用于表示一个字符集合。在一个集合中：

            字符可以单独列出，比如 [amk] 匹配 'a'， 'm'， 或者 'k'。

            可以表示字符范围，通过用 '-' 将两个字符连起来。比如 [a-z] 将匹配任何小写<ASCII码>字符， [0-5][0-9] 将匹配从 00 到 59 的两位数字， [0-9A-Fa-f] 将匹配任何十六进制数位。 
            如果 - 进行了转义 （比如 [a\-z]）或者它的位置在首位或者末尾（如 [-a] 或 [a-]），它就只表示普通字符 '-'。

            特殊字符在集合中，失去它的特殊含义。比如 [(+*)] 只会匹配这几个文法字符 '(', '+', '*', or ')'。

            字符类如 \w 或者 \S (如下定义) 在集合内可以接受，它们可以匹配的字符由 <ASCII码> 或者 <地区> 模式决定。

            不在集合范围内的字符可以通过 取反 来进行匹配。如果集合首字符是 '^' ，所有 不 在集合内的字符将会被匹配，比如 [^5] 将匹配所有字符，除了 '5'， [^^] 将匹配所有字符，
            除了 '^'. ^ 如果不在集合首位，就没有特殊含义。

            在集合内要匹配一个字符 ']'，有两种方法，要么就在它之前加上反斜杠，要么就把它放到集合首位。比如， [()[\]{}] 和 []()[{}] 都可以匹配括号。

            <统一码> 技术标准 #18 里的嵌套集合和集合操作支持可能在未来添加。这将会改变语法，所以为了帮助这个改变，一个 未来警告 将会在有多义的情况里被 <报>，包含以下几种情况，
            集合由 '[' 开始，或者包含下列字符序列 '--', '&&', '~~', 和 '||'。为了避免警告，需要将它们用反斜杠转义。
    "|"      A|B， A 和 B 可以是任意正则表达式，创建一个正则表达式，匹配 A 或者 B. 任意个正则表达式可以用 '|' 连接。它也可以在组合（见下列）内使用。扫描目标字符串时， 
             '|' 分隔开的正则样式从左到右进行匹配。当一个样式完全匹配时，这个分支就被接受。意思就是，一旦 A 匹配成功， B 就不再进行匹配，即便它能产生一个更好的匹配。或者说，
             '|' 操作符绝不贪婪。 如果要匹配 '|' 字符，使用 \|， 或者把它包含在字符集里，比如 [|].
    (...)    （组合），匹配括号内的任意正则表达式，并标识出组合的开始和结尾。匹配完成后，组合的内容可以被获取，并可以在之后用 \数字 转义序列进行再次匹配，
             之后进行详细说明。要匹配字符 '(' 或者 ')', 用 \( 或 \), 或者把它们包含在字符集合里: [(], [)].
    (?aiLmsux) ( 'a', 'i', 'L', 'm', 's', 'u', 'x' 中的一个或多个) 这个组合匹配一个空字符串；这些字符对正则表达式设置以下标记 正则.A (只匹配ASCII字符), 正则.I (忽略大小写), 正则.L (语言依赖),
               正则.M (多行模式), 正则.S (<点全部>匹配全部字符), 正则.U (<统一码>匹配), and 正则.X (冗长模式)。 (这些标记在 模块内容 中描述) 如果你想将这些标记包含在正则表达式中，这个方法就很有用，
               免去了在 正则.编译() 中传递 <标志> 参数。标记应该在表达式字符串首位表示。
    (?:...)  正则括号的非捕获版本。 匹配在括号内的任何正则表达式，但该分组所匹配的子字符串 不能 在执行匹配后被获取或是之后在模式中被引用。
    (?P<名称>...) （命名组合）类似正则组合，但是匹配到的子串组在外部是通过定义的 <名称> 来获取的。组合名必须是有效的 草蟒Python标识符，并且每个组合名只能用一个正则表达式定义，只能定义一次。
                   一个符号组合同样是一个数字组合，就像这个组合没有被命名一样。
                   命名组合可以在三种上下文中引用。如果样式是 (?P<quote>['"]).*?(?P=quote) （也就是说，匹配单引号或者双引号括起来的字符串)：
    (?P=名称)     反向引用一个命名组合；它匹配前面那个叫 名称 的命名组中匹配到的串同样的字串。
    (?#...)  注释；里面的内容会被忽略。
    (?=...)  匹配 … 的内容，接下来匹配，但不使用字符串。
    (?!...)  匹配 … 接下来不匹配
    (?<=...) 匹配字符串的当前位置，它的前面匹配 … 的内容到当前位置。(必须有固定的长度)
    (?(id/名称)yes|no) 如果ID /名称 匹配的组匹配，则匹配yes模式，(可选)无模式，否则。

由 '\' 和一个字符组成的特殊序列在以下列出。 如果普通字符不是<ASCII码>数位或者<ASCII码>字母，那么正则样式将匹配第二个字符。比如，\$ 匹配字符 '$'.
    \数字  匹配数字代表的组合。每个括号是一个组合，组合从1开始编号。比如 (.+) \1 匹配 'the the' 或者 '55 55', 但不会匹配 'thethe' (注意组合后面的空格)。
             这个特殊序列只能用于匹配前面99个组合。如果 <数字> 的第一个数位是0， 或者 <数字> 是三个八进制数，它将不会被看作是一个组合，而是八进制的数字值。
             在 '[' 和 ']' 字符集合内，任何数字转义都被看作是字符。
    \A       只匹配字符串开始。
    \Z       只匹配字符串尾。
    \b       匹配空字符串，但只在单词开始或结尾的位置。一个单词被定义为一个单词字符的序列。注意，通常 \b 定义为 \w 和 \W 字符之间，或者 \w 和字符串开始/结尾的边界， 
             意思就是 r'\bfoo\b' 匹配 'foo', 'foo.', '(foo)', 'bar foo baz' 但不匹配 'foobar' 或者 'foo3'。

             默认情况下，<统一码>字母和数字是在<统一码>样式中使用的，但是可以用 <ASCII码> 标记来更改。如果 LOCALE 标记被设置的话，词的边界是由当前语言区域设置决定的，\b 表示退格字符，以便与Python字符串文本兼容。
    \B       匹配空字符串，但 不 能在词的开头或者结尾。意思就是 r'py\B' 匹配 'python', 'py3', 'py2', 但不匹配 'py', 'py.', 或者 'py!'. \B 是 \b 的取非，所以<统一码>样式的词语是由<统一码>字母，数字或下划线构成的，
             虽然可以用 <ASCII码> 标志来改变。如果使用了 <地区> 标志，则词的边界由当前语言区域设置。
    \d       对于 <统一码> (字符串) 样式：匹配任何<统一码>十进制数（就是在<字符串>字符目录[Nd]里的字符）。这包括了 [0-9] ，和很多其他的数字字符。如果设置了 <ASCII码> 标志，就只匹配 [0-9] 。

             对于8位(字节)样式：匹配任何十进制数，就是 [0-9]。
    \D       匹配任何非十进制数字的字符。就是 \d 取非。 如果设置了 <ASCII码> 标志，就相当于 [^0-9] 。
    \s       对于 <统一码> (字符串) 样式：匹配任何<统一码>空白字符（包括 [ \t\n\r\f\v] ，还有很多其他字符，比如不同语言排版规则约定的不换行空格）。如果 <统一码> 被设置，就只匹配 [ \t\n\r\f\v] 。

             对于8位(字节)样式：匹配<ASCII码>中的空白字符，就是 [ \t\n\r\f\v] 。
    \S       匹配任何非空白字符。就是 \s 取非。如果设置了 <ASCII码> 标志，就相当于 [^ \t\n\r\f\v] 。
    \w       对于 <统一码> (字符串) 样式：匹配<统一码>词语的字符，包含了可以构成词语的绝大部分字符，也包括数字和下划线。如果设置了 <ASCII码> 标志，就只匹配 [a-zA-Z0-9_] 。

             对于8位(字节)样式：匹配<ASCII码>字符中的数字和字母和下划线，就是 [a-zA-Z0-9_] 。如果设置了 <地区> 标记，就匹配当前语言区域的数字和字母和下划线。
    \W       匹配任何不是单词字符的字符。 这与 \w 正相反。 如果使用了 <ASCII码> 旗标，这就等价于 [^a-zA-Z0-9_]。 如果使用了 <地区> 旗标，则会匹配在当前区域设置中不是字母数字又不是下划线的字符。
    \\       匹配反斜杠

该模块导出以下功能:
    匹配        将正则表达式字符匹配到字符串的开头
    完全匹配    将正则表达式字符匹配到所有字符串。
    搜索        在字符串中搜索是否存在可以匹配的结果。
    替换        替换在字符串中找到的结果。
    替换n       与<替换>相同，但它返回进行的替换次数。
    分割        通过表达式的出现来分割字符串。
    查找所有    查找字符串中所有出现的结果。
    查找迭代    返回一个迭代器，为每个匹配项生成一个匹配对象。
    编译        将表达式编译成<模式类>对象。
    清除缓存    清除正则表达式缓存。
    转义字符    在字符串中反斜杠所有非字母数字。

该模块中的某些功能将 标志 用作可选参数：
    A  ASCII码       让 \w, \W, \b, \B, \d, \D, \s 和 \S 只匹配<ASCII码>，而不是<统一码>。这只对<统一码>样式有效，会被<字节>样式忽略。相当于前面语法中的内联标志 (?a) 。

                   注意，为了保持向后兼容， 正则.U 标记依然存在（还有他的同义 正则.统一码 和嵌入形式 (?u) ) ， 但是这些在 草蟒Python 3 是冗余的，因为默认字符串已经是<统一码>了（并且<统一码>匹配不允许字节出现)。
    I  忽略大小写  执行不区分大小写的匹配.
    L  地区      执行 \w, \W, \b, \B,取决于当前的语言环境。
    M  多行   设置以后，样式字符 '^' 匹配字符串的开始，和每一行的开始（换行符后面紧跟的符号）；样式字符 '$' 匹配字符串尾，和每一行的结尾（换行符前面那个符号）。
                   默认情况下，’^’ 匹配字符串头，'$' 匹配字符串尾。对应内联标记 (?m) 。
    S  点全部      让 '.' 特殊字符匹配任何字符，包括换行符；如果没有这个标记，'.' 就匹配 除了 换行符的其他任意字符。对应内联标记 (?s) 。
    X  详细     这个标记允许你编写更具可读性更友好的正则表达式。通过分段和添加注释。空白符号会被忽略，除非在一个字符集合当中或者由反斜杠转义，或者在 *?, (?: or (?P<…> 分组之内。
                   当一个行内有 # 不在字符集和转义序列，那么它之后的所有字符都是注释。
    U  统一码     仅出于兼容性。 将忽略字符串模式（默认设置），并禁止使用字节模式。

该模块还定义了异常 <异常>。

"""

__version__ = "2.2.1"
_汉化人='lwdnxu'
_汉化版本 = "2019.12.06 - 草蟒380 - 2019.11.29"
# if __main__=='__name__':
导入 re
导入 enum
#导入 sre_compile

__all__ = [
    "匹配", "完全匹配", "搜索", "替换", "替换n", "分割",
    "查找所有", "查找迭代", "编译", "清除缓存", "模板", "转义字符",
    "错误", "模式类", "匹配类", "A", "I", "L", "M", "S", "X", "U",
    "ASCII码", "忽略大小写", "地区", "多行", "点全部", "详细",
    "统一码",
]

类 正则标志(enum.IntFlag):
    pass

ASCII码 = A = re.ASCII
忽略大小写 = I = re.IGNORECASE 
地区 = L = re.LOCALE 
统一码 = U = re.UNICODE 
多行 = M = re.MULTILINE 
点全部 = S = re.DOTALL 
详细 = X = re.VERBOSE 
模板 = T = re.TEMPLATE 

错误 = re.error

函 匹配(模式,字符串, 标志=0):
    """如果字符串开始的0或者多个字符匹配到了正则表达式样式，就返回一个
    相应的 匹配对象 。 如果没有匹配，就返回 空。 """
    return re.match(模式,字符串,标志)

函 完全匹配(模式,字符串, 标志=0):
    """如果整个字符串匹配到正则表达式样式，就返回一个相应的匹配对象 。
    否则就返回一个 空。 """
    return re.fullmatch(模式,字符串, 标志)

函 搜索(模式,字符串, 标志=0):
    """扫描整个 “字符串” 找到匹配样式的第一个位置，并返回一个相应的匹配对象。
    如果没有匹配，就返回一个 空。"""
    return re.search(模式,字符串, 标志)

函 替换(模式,替换为,字符串, 计数=0, 标志=0):
    """返回通过使用 “替换为” 替换在 “字符串” 最左边非重叠出现的 模式” 而
    获得的字符串。 如果样式没有找到，则不加改变地返回 “字符串”。 “替换为” 可
    以是字符串或函数；如为字符串，则其中任何反斜杠转义序列都会被处理。 
    也就是说，\n 会被转换为一个换行符，\r 会被转换为一个回车附，依此类推。
    未知的 ASCII 字符转义序列保留在未来使用，会被当作错误来处理。 其他
    未知转义序列例如 \& 会保持原样。 向后引用像是 \6 会用样式中第 6 组所
    匹配到的子字符串来替换。"""
    return re.sub(模式,替换为,字符串, 计数, 标志)

函 替换n(模式,替换为,字符串, 计数=0, 标志=0):
    """行为与 替换() 相同，但是返回一个元组 (字符串, 替换次数)."""
    return re.subn(模式,替换为,字符串, 计数, 标志)

函 分割(模式,字符串, 最大分割=0, 标志=0):
    """用 “模式” 分开 “字符串” 。 如果在 “模式” 中捕获到括号，那么
    所有的组里的文字也会包含在列表里。如果 maxsplit 非零， 最多进行 
    maxsplit 次分隔， 剩下的字符全部返回到列表的最后一个元素。"""
    return re.split(模式,字符串, 最大分割, 标志)

函 查找所有(模式,字符串, 标志=0):
    """对 “字符串” 返回一个不重复的 “模式” 的匹配列表， “字符串” 从左到
    右进行扫描，匹配按找到的顺序返回。如果样式里存在一到多个组，就返回
    一个组合列表；就是一个元组的列表（如果样式里有超过一个组合的话）。
    空匹配也会包含在结果里。"""
    return re.findall(模式,字符串, 标志)

函 查找迭代(模式,字符串, 标志=0):
    """“模式” 在 “字符串” 里所有的非重复匹配，返回为一个迭代器 保存了
     匹配对象 。 “字符串” 从左到右扫描，匹配按顺序排列。空匹配也包
    含在结果里。"""
    return re.finditer(模式,字符串, 标志)

函 编译(模式,标志=0):
    """编译一个正则表达式”模式“，返回一个“模式”对象"""
    return re.compile(模式,标志)

函 清除缓存():
    """清除正则表达式缓存。"""
    re.purge()

函 模板(模式,标志=0):
    """编译一个 “模板”  “模式”，返回一个“模式”对象"""
    return re.template(模式,标志)

函 转义字符(模式):
    """
    转义 “模式” 中的特殊字符
    """
    return re.escape(模式)

匹配类 = re.Match
模式类 = re.Pattern

类 扫描器类(re.Scanner):
    pass
